from fastapi import Request
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant
from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.service.dict_service import DictDataService
from module_plant.dao.task_dao import TaskDao
from module_plant.entity.vo.task_vo import DeleteTaskModel, TaskModel, TaskPageQueryModel
from utils.common_util import CamelCaseUtil
from utils.excel_util import ExcelUtil


class TaskService:
    """
    种植任务明细模块服务层
    """

    @classmethod
    async def get_task_list_services(
        cls, query_db: AsyncSession, query_object: TaskPageQueryModel, is_page: bool = False
    ):
        """
        获取种植任务明细列表信息service

        :param query_db: orm对象
        :param query_object: 查询参数对象
        :param is_page: 是否开启分页
        :return: 种植任务明细列表信息对象
        """
        task_list_result = await TaskDao.get_task_list(query_db, query_object, is_page)

        return task_list_result


    @classmethod
    async def add_task_services(cls, query_db: AsyncSession, page_object: TaskModel):
        """
        新增种植任务明细信息service

        :param query_db: orm对象
        :param page_object: 新增种植任务明细对象
        :return: 新增种植任务明细校验结果
        """
        try:
            await TaskDao.add_task_dao(query_db, page_object)
            await query_db.commit()
            return CrudResponseModel(is_success=True, message='新增成功')
        except Exception as e:
            await query_db.rollback()
            raise e

    @classmethod
    async def edit_task_services(cls, query_db: AsyncSession, page_object: TaskModel):
        """
        编辑种植任务明细信息service

        :param query_db: orm对象
        :param page_object: 编辑种植任务明细对象
        :return: 编辑种植任务明细校验结果
        """
        edit_task = page_object.model_dump(exclude_unset=True, exclude={'task_leader', 'scheduled_start_time', 'scheduled_end_time', })
        task_info = await cls.task_detail_services(query_db, page_object.task_id)
        if task_info.task_id:
            try:
                await TaskDao.edit_task_dao(query_db, edit_task)
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='更新成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='种植任务明细不存在')

    @classmethod
    async def delete_task_services(cls, query_db: AsyncSession, page_object: DeleteTaskModel):
        """
        删除种植任务明细信息service

        :param query_db: orm对象
        :param page_object: 删除种植任务明细对象
        :return: 删除种植任务明细校验结果
        """
        if page_object.task_ids:
            task_id_list = page_object.task_ids.split(',')
            try:
                for task_id in task_id_list:
                    await TaskDao.delete_task_dao(query_db, TaskModel(taskId=task_id))
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='删除成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='传入任务Id为空')

    @classmethod
    async def task_detail_services(cls, query_db: AsyncSession, task_id: int):
        """
        获取种植任务明细详细信息service

        :param query_db: orm对象
        :param task_id: 任务Id
        :return: 任务Id对应的信息
        """
        task = await TaskDao.get_task_detail_by_id(query_db, task_id=task_id)
        if task:
            result = TaskModel(**CamelCaseUtil.transform_result(task))
        else:
            result = TaskModel(**dict())

        return result

    @staticmethod
    async def export_task_list_services(request: Request, task_list: List):
        """
        导出种植任务明细信息service

        :param task_list: 种植任务明细信息列表
        :return: 种植任务明细信息对应excel的二进制数据
        """
        # 创建一个映射字典，将英文键映射到中文键
        mapping_dict = {
            'taskId': '任务Id',
            'taskName': '任务名称',
            'taskLeaderId': '责任人Id',
            'taskType': '任务类型',
            'taskLeader': '责任人',
            'scheduledStartTime': '计划开始时间',
            'scheduledEndTime': '计划结束时间',
            'actualStartTime': '实际开始时间',
            'actualEndTime': '实际结束时间',
            'taskDescription': '任务详情',
            'plantPlotId': '关联地块id',
            'plantPlotName': '关联地块',
            'planterId': '种植主体Id',
            'planterName': '种植主体',
            'productAreaId': '产区id',
            'productAreaName': '产区',
            'year': '数据年份',
            'isOntime': '是否按时完成',
        }
        product_area_list = await DictDataService.query_dict_data_list_from_cache_services(
            request.app.state.redis, dict_type='product_area'
        )
        product_area_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in product_area_list]
        product_area_option_dict = {item.get('value'): item for item in product_area_option}
        task_type_list = await DictDataService.query_dict_data_list_from_cache_services(
            request.app.state.redis, dict_type='task_type'
        )
        task_type_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in task_type_list]
        task_type_option_dict = {item.get('value'): item for item in task_type_option}
        for item in task_list:
            if str(item.get('taskType')) in task_type_option_dict.keys():
                item['taskType'] = task_type_option_dict.get(str(item.get('taskType'))).get('label')
            if str(item.get('productAreaId')) in product_area_option_dict.keys():
                item['productAreaId'] = product_area_option_dict.get(str(item.get('productAreaId'))).get('label')
        binary_data = ExcelUtil.export_list2excel(task_list, mapping_dict)

        return binary_data
